package com.zenithmind.user.controller;

import com.zenithmind.common.annotation.Log;
import com.zenithmind.common.constant.OperationTypeEnum;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import com.zenithmind.user.controller.base.BaseController;
import com.zenithmind.user.pojo.query.UserQuery;
import com.zenithmind.user.pojo.vo.UserVO;
import com.zenithmind.user.service.domain.UserQueryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.constraints.NotBlank;
import java.util.List;

/**
 * 用户查询控制器
 * 遵循单一职责原则：专门处理用户查询相关功能
 * 遵循接口隔离原则：只提供查询相关的接口
 */
@Slf4j
@RestController
@RequestMapping("/api/zenithMind/user")
@RequiredArgsConstructor
@Tag(name = "用户查询", description = "用户信息查询相关接口")
public class UserQueryController extends BaseController {

    private final UserQueryService userQueryService;

    /**
     * 根据ID查询用户信息接口
     */
    @Log(description = "根据ID查询用户信息", operationType = OperationTypeEnum.QUERY)
    @GetMapping("/getUserById")
    @Operation(summary = "根据ID查询用户信息", description = "根据用户ID获取用户详细信息")
    public Result<UserVO> getUserById(
            @Parameter(description = "用户ID", required = true)
            @RequestParam("userId") @NotBlank(message = "用户ID不能为空") String userId) {
        
        logOperation("根据ID查询用户信息", userId);
        
        try {
            UserVO userVO = userQueryService.getUserVOById(userId);
            if (userVO != null) {
                logSuccess("根据ID查询用户信息", userVO.getUsername());
                return success(userVO);
            } else {
                logFailure("根据ID查询用户信息", "用户不存在");
                return fail("用户不存在");
            }
        } catch (Exception e) {
            logFailure("根据ID查询用户信息", e.getMessage());
            throw e;
        }
    }

    /**
     * 查询当前登录的用户信息接口
     */
    @Log(description = "查询当前登录用户信息", operationType = OperationTypeEnum.QUERY)
    @GetMapping("/getCurrentUser")
    @Operation(summary = "查询当前登录的用户信息", description = "获取当前登录用户的详细信息")
    public Result<UserVO> getCurrentUser() {
        logOperation("查询当前登录用户信息");
        
        try {
            UserVO userVO = userQueryService.getCurrentUser();
            if (userVO != null) {
                logSuccess("查询当前登录用户信息", userVO.getUsername());
                return success(userVO);
            } else {
                logFailure("查询当前登录用户信息", "未找到当前用户信息");
                return fail("未找到当前用户信息");
            }
        } catch (Exception e) {
            logFailure("查询当前登录用户信息", e.getMessage());
            throw e;
        }
    }

    /**
     * 分页查询用户信息接口（适用于后台管理系统）
     */
    @Log(description = "分页查询用户信息", operationType = OperationTypeEnum.QUERY)
    @GetMapping("/userPage")
    @Operation(summary = "分页查询用户信息", description = "分页查询用户列表，适用于后台管理系统")
    @PreAuthorize("hasRole('ADMIN') or hasRole('SUPER_ADMIN')")
    public Result<PageResult<UserVO>> getUserPage(UserQuery userQuery) {
        logOperation("分页查询用户信息", userQuery.getCurrent(), userQuery.getSize());
        
        try {
            PageResult<UserVO> pageResult = userQueryService.getUserPage(userQuery);
            logSuccess("分页查询用户信息", "查询到 " + pageResult.getTotal() + " 条记录");
            return success(pageResult);
        } catch (Exception e) {
            logFailure("分页查询用户信息", e.getMessage());
            throw e;
        }
    }

    /**
     * 根据用户名查询用户信息
     */
    @Log(description = "根据用户名查询用户信息", operationType = OperationTypeEnum.QUERY)
    @GetMapping("/getUserByUsername")
    @Operation(summary = "根据用户名查询用户信息", description = "根据用户名获取用户信息")
    @PreAuthorize("hasRole('ADMIN') or hasRole('SUPER_ADMIN')")
    public Result<UserVO> getUserByUsername(
            @Parameter(description = "用户名", required = true)
            @RequestParam("username") @NotBlank(message = "用户名不能为空") String username) {
        
        logOperation("根据用户名查询用户信息", username);
        
        try {
            UserVO userVO = userQueryService.getUserVOById(
                userQueryService.getUserByUsername(username).getId()
            );
            
            if (userVO != null) {
                logSuccess("根据用户名查询用户信息", userVO.getUsername());
                return success(userVO);
            } else {
                logFailure("根据用户名查询用户信息", "用户不存在");
                return fail("用户不存在");
            }
        } catch (Exception e) {
            logFailure("根据用户名查询用户信息", e.getMessage());
            throw e;
        }
    }

    /**
     * 批量查询用户信息
     */
    @Log(description = "批量查询用户信息", operationType = OperationTypeEnum.QUERY)
    @PostMapping("/getUsersByIds")
    @Operation(summary = "批量查询用户信息", description = "根据用户ID列表批量获取用户信息")
    @PreAuthorize("hasRole('ADMIN') or hasRole('SUPER_ADMIN')")
    public Result<List<UserVO>> getUsersByIds(
            @Parameter(description = "用户ID列表", required = true)
            @RequestBody List<String> userIds) {
        
        logOperation("批量查询用户信息", userIds.size() + " 个用户");
        
        try {
            if (userIds == null || userIds.isEmpty()) {
                return fail("用户ID列表不能为空");
            }
            
            if (userIds.size() > 100) {
                return fail("批量查询用户数量不能超过100个");
            }
            
            List<UserVO> users = userIds.stream()
                    .map(userQueryService::getUserVOById)
                    .filter(userVO -> userVO != null)
                    .toList();
            
            logSuccess("批量查询用户信息", "查询到 " + users.size() + " 个用户");
            return success(users);
        } catch (Exception e) {
            logFailure("批量查询用户信息", e.getMessage());
            throw e;
        }
    }

    /**
     * 检查用户名是否存在
     */
    @Log(description = "检查用户名是否存在", operationType = OperationTypeEnum.QUERY)
    @GetMapping("/checkUsername")
    @Operation(summary = "检查用户名是否存在", description = "检查指定用户名是否已被使用")
    public Result<Boolean> checkUsername(
            @Parameter(description = "用户名", required = true)
            @RequestParam("username") @NotBlank(message = "用户名不能为空") String username) {
        
        logOperation("检查用户名是否存在", username);
        
        try {
            boolean exists = userQueryService.existsByUsername(username);
            logSuccess("检查用户名是否存在", exists ? "用户名已存在" : "用户名可用");
            return success(exists);
        } catch (Exception e) {
            logFailure("检查用户名是否存在", e.getMessage());
            throw e;
        }
    }

    /**
     * 检查邮箱是否存在
     */
    @Log(description = "检查邮箱是否存在", operationType = OperationTypeEnum.QUERY)
    @GetMapping("/checkEmail")
    @Operation(summary = "检查邮箱是否存在", description = "检查指定邮箱是否已被使用")
    public Result<Boolean> checkEmail(
            @Parameter(description = "邮箱", required = true)
            @RequestParam("email") @NotBlank(message = "邮箱不能为空") String email) {
        
        logOperation("检查邮箱是否存在", email);
        
        try {
            boolean exists = userQueryService.existsByEmail(email);
            logSuccess("检查邮箱是否存在", exists ? "邮箱已存在" : "邮箱可用");
            return success(exists);
        } catch (Exception e) {
            logFailure("检查邮箱是否存在", e.getMessage());
            throw e;
        }
    }

    /**
     * 获取用户统计信息
     */
    @Log(description = "获取用户统计信息", operationType = OperationTypeEnum.QUERY)
    @GetMapping("/statistics")
    @Operation(summary = "获取用户统计信息", description = "获取用户总数、活跃用户数等统计信息")
    @PreAuthorize("hasRole('ADMIN') or hasRole('SUPER_ADMIN')")
    public Result<UserStatistics> getUserStatistics() {
        logOperation("获取用户统计信息");
        
        try {
            long totalUsers = userQueryService.countUsers();
            long activeUsers = userQueryService.countActiveUsers();
            
            UserStatistics statistics = new UserStatistics(totalUsers, activeUsers);
            logSuccess("获取用户统计信息", "总用户数: " + totalUsers + ", 活跃用户数: " + activeUsers);
            return success(statistics);
        } catch (Exception e) {
            logFailure("获取用户统计信息", e.getMessage());
            throw e;
        }
    }

    /**
     * 用户统计信息内部类
     */
    public static class UserStatistics {
        private final long totalUsers;
        private final long activeUsers;
        
        public UserStatistics(long totalUsers, long activeUsers) {
            this.totalUsers = totalUsers;
            this.activeUsers = activeUsers;
        }
        
        public long getTotalUsers() { return totalUsers; }
        public long getActiveUsers() { return activeUsers; }
        public double getActiveRate() { 
            return totalUsers > 0 ? (double) activeUsers / totalUsers * 100 : 0; 
        }
    }
}
